"""RPA框架日志查看器组件"""

import os
import time
from datetime import datetime
from PyQt5.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, 
    QGroupBox, QTreeWidget, QTreeWidgetItem, QTabWidget, QTextEdit,
    QTableWidget, QTableWidgetItem, QHeaderView, QLineEdit, 
    QComboBox, QCheckBox, QSpinBox, QDoubleSpinBox, QColorDialog,
    QFileDialog, QMessageBox, QSplitter, QToolBar, QMenu, QAction,
    QDateTimeEdit, QStatusBar, QProgressBar
)
from PyQt5.QtCore import Qt, pyqtSignal, QThread, QTimer
from PyQt5.QtGui import QFont, QColor, QFontMetrics, QIcon, QTextCursor

# 使用标准logging模块
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger("rpa.gui.log_viewer")


class LogViewerWidget(QWidget):
    """日志查看器组件"""
    
    # 定义信号
    log_opened = pyqtSignal(str)  # log_path
    log_exported = pyqtSignal(str)  # export_path
    
    def __init__(self):
        super().__init__()
        
        # 当前日志文件路径
        self.current_log_path = None
        
        # 日志监控线程
        self.monitor_thread = None
        self.stop_monitoring = False
        
        # 日志级别颜色映射
        self.log_level_colors = {
            "DEBUG": QColor(0, 100, 0),    # 深绿色
            "INFO": QColor(0, 0, 255),     # 蓝色
            "WARNING": QColor(255, 140, 0),  # 橙色
            "ERROR": QColor(255, 0, 0),    # 红色
            "CRITICAL": QColor(128, 0, 0)  # 深红色
        }
        
        # 初始化UI
        self._init_ui()
    
    def _init_ui(self):
        """初始化UI组件"""
        main_layout = QVBoxLayout(self)
        
        # 工具栏
        toolbar = QToolBar("日志查看器工具栏")
        
        # 打开日志文件
        open_action = QPushButton("打开日志文件")
        open_action.clicked.connect(self.open_log_file)
        toolbar.addWidget(open_action)
        
        # 刷新日志
        refresh_action = QPushButton("刷新")
        refresh_action.clicked.connect(self.refresh_log)
        toolbar.addWidget(refresh_action)
        
        # 清空日志
        clear_action = QPushButton("清空")
        clear_action.clicked.connect(self.clear_log)
        toolbar.addWidget(clear_action)
        
        # 导出日志
        export_action = QPushButton("导出日志")
        export_action.clicked.connect(self.export_log)
        toolbar.addWidget(export_action)
        
        # 监控日志
        self.monitor_check = QCheckBox("实时监控")
        self.monitor_check.stateChanged.connect(self.toggle_monitoring)
        toolbar.addWidget(self.monitor_check)
        
        main_layout.addWidget(toolbar)
        
        # 搜索和过滤
        filter_layout = QHBoxLayout()
        
        # 日志级别过滤
        level_filter_label = QLabel("级别:")
        self.level_filter_combo = QComboBox()
        self.level_filter_combo.addItems(["全部", "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"])
        self.level_filter_combo.currentIndexChanged.connect(self.filter_logs)
        
        # 搜索框
        search_label = QLabel("搜索:")
        self.search_edit = QLineEdit()
        self.search_edit.setPlaceholderText("输入搜索关键词...")
        self.search_edit.textChanged.connect(self.filter_logs)
        
        # 搜索按钮
        search_button = QPushButton("搜索")
        search_button.clicked.connect(self.filter_logs)
        
        # 重置过滤
        reset_filter_button = QPushButton("重置过滤")
        reset_filter_button.clicked.connect(self.reset_filter)
        
        filter_layout.addWidget(level_filter_label)
        filter_layout.addWidget(self.level_filter_combo)
        filter_layout.addWidget(search_label)
        filter_layout.addWidget(self.search_edit)
        filter_layout.addWidget(search_button)
        filter_layout.addWidget(reset_filter_button)
        
        main_layout.addLayout(filter_layout)
        
        # 创建分割器
        splitter = QSplitter(Qt.Orientation.Horizontal)
        
        # 左侧日志统计和信息
        stats_widget = QWidget()
        stats_layout = QVBoxLayout(stats_widget)
        
        # 日志信息
        info_group = QGroupBox("日志信息")
        info_group_layout = QVBoxLayout(info_group)
        
        # 日志文件路径
        path_layout = QHBoxLayout()
        path_layout.addWidget(QLabel("日志文件:"))
        self.log_path_label = QLabel("未设置")
        self.log_path_label.setWordWrap(True)
        path_layout.addWidget(self.log_path_label)
        info_group_layout.addLayout(path_layout)
        
        # 文件大小
        size_layout = QHBoxLayout()
        size_layout.addWidget(QLabel("文件大小:"))
        self.file_size_label = QLabel("0 KB")
        size_layout.addWidget(self.file_size_label)
        info_group_layout.addLayout(size_layout)
        
        # 最后修改时间
        modified_layout = QHBoxLayout()
        modified_layout.addWidget(QLabel("最后修改:"))
        self.modified_time_label = QLabel("未知")
        modified_layout.addWidget(self.modified_time_label)
        info_group_layout.addLayout(modified_layout)
        
        stats_layout.addWidget(info_group)
        
        # 日志统计
        count_group = QGroupBox("日志统计")
        count_group_layout = QVBoxLayout(count_group)
        
        # 总日志数
        total_layout = QHBoxLayout()
        total_layout.addWidget(QLabel("总日志数:"))
        self.total_count_label = QLabel("0")
        total_layout.addWidget(self.total_count_label)
        count_group_layout.addLayout(total_layout)
        
        # 各级别日志数
        levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
        self.level_count_labels = {}
        
        for level in levels:
            level_layout = QHBoxLayout()
            level_label = QLabel(f"{level}:")
            count_label = QLabel("0")
            
            # 设置标签颜色
            if level in self.log_level_colors:
                level_label.setStyleSheet(f"color: {self.log_level_colors[level].name()}")
                count_label.setStyleSheet(f"color: {self.log_level_colors[level].name()}")
            
            level_layout.addWidget(level_label)
            level_layout.addWidget(count_label)
            count_group_layout.addLayout(level_layout)
            
            self.level_count_labels[level] = count_label
        
        stats_layout.addWidget(count_group)
        
        # 时间范围过滤
        time_range_group = QGroupBox("时间范围过滤")
        time_range_group_layout = QVBoxLayout(time_range_group)
        
        # 开始时间
        start_layout = QHBoxLayout()
        start_layout.addWidget(QLabel("开始时间:"))
        self.start_time_edit = QDateTimeEdit()
        self.start_time_edit.setCalendarPopup(True)
        self.start_time_edit.setDateTime(datetime.now().replace(hour=0, minute=0, second=0, microsecond=0))
        start_layout.addWidget(self.start_time_edit)
        time_range_group_layout.addLayout(start_layout)
        
        # 结束时间
        end_layout = QHBoxLayout()
        end_layout.addWidget(QLabel("结束时间:"))
        self.end_time_edit = QDateTimeEdit()
        self.end_time_edit.setCalendarPopup(True)
        self.end_time_edit.setDateTime(datetime.now().replace(hour=23, minute=59, second=59, microsecond=0))
        end_layout.addWidget(self.end_time_edit)
        time_range_group_layout.addLayout(end_layout)
        
        # 应用时间过滤
        apply_time_filter_button = QPushButton("应用时间过滤")
        apply_time_filter_button.clicked.connect(self.filter_logs_by_time)
        time_range_group_layout.addWidget(apply_time_filter_button)
        
        stats_layout.addWidget(time_range_group)
        
        stats_layout.addStretch()
        
        # 添加到分割器
        splitter.addWidget(stats_widget)
        
        # 右侧日志内容
        log_widget = QWidget()
        log_layout = QVBoxLayout(log_widget)
        
        # 日志内容标签页
        self.log_tabs = QTabWidget()
        
        # 表格视图
        self.table_tab = QWidget()
        self.table_layout = QVBoxLayout(self.table_tab)
        
        self.log_table = QTableWidget()
        self.log_table.setColumnCount(4)
        self.log_table.setHorizontalHeaderLabels(["时间", "级别", "来源", "消息"])
        
        # 设置表头样式
        header = self.log_table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.ResizeMode.ResizeToContents)
        header.setSectionResizeMode(1, QHeaderView.ResizeMode.ResizeToContents)
        header.setSectionResizeMode(2, QHeaderView.ResizeMode.ResizeToContents)
        header.setSectionResizeMode(3, QHeaderView.ResizeMode.Stretch)
        
        # 设置右键菜单
        self.log_table.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
        self.log_table.customContextMenuRequested.connect(self.show_table_context_menu)
        
        self.table_layout.addWidget(self.log_table)
        
        self.log_tabs.addTab(self.table_tab, "表格视图")
        
        # 文本视图
        self.text_tab = QWidget()
        self.text_layout = QVBoxLayout(self.text_tab)
        
        self.log_text = QTextEdit()
        self.log_text.setReadOnly(True)
        self.log_text.setLineWrapMode(QTextEdit.LineWrapMode.NoWrap)
        
        # 设置等宽字体
        font = QFont("Consolas", 9)
        self.log_text.setFont(font)
        
        self.text_layout.addWidget(self.log_text)
        
        self.log_tabs.addTab(self.text_tab, "文本视图")
        
        # 详细信息视图
        self.detail_tab = QWidget()
        self.detail_layout = QVBoxLayout(self.detail_tab)
        
        detail_group = QGroupBox("日志详情")
        detail_group_layout = QVBoxLayout(detail_group)
        
        # 详细信息文本框
        self.detail_text = QTextEdit()
        self.detail_text.setReadOnly(True)
        detail_group_layout.addWidget(self.detail_text)
        
        self.detail_layout.addWidget(detail_group)
        
        self.log_tabs.addTab(self.detail_tab, "详细信息")
        
        log_layout.addWidget(self.log_tabs)
        
        # 添加到分割器
        splitter.addWidget(log_widget)
        
        # 设置分割器比例
        splitter.setSizes([300, 700])
        
        main_layout.addWidget(splitter)
        
        # 状态栏
        status_layout = QHBoxLayout()
        self.status_label = QLabel("就绪")
        status_layout.addWidget(self.status_label)
        status_layout.addStretch()
        
        # 显示当前过滤信息
        self.filter_info_label = QLabel("无过滤")
        status_layout.addWidget(self.filter_info_label)
        
        main_layout.addLayout(status_layout)
        
        # 设置表格点击事件
        self.log_table.cellClicked.connect(self.on_table_cell_clicked)
    
    def open_log_file(self):
        """打开日志文件"""
        file_path, _ = QFileDialog.getOpenFileName(
            self, 
            "打开日志文件", 
            "", 
            "日志文件 (*.log *.txt);;所有文件 (*)"
        )
        
        if file_path:
            try:
                # 停止之前的监控
                self.stop_monitoring = True
                if self.monitor_thread:
                    self.monitor_thread.wait()
                    self.monitor_thread = None
                
                # 更新当前日志路径
                self.current_log_path = file_path
                
                # 读取日志文件
                self._read_log_file(file_path)
                
                # 更新日志信息
                self._update_log_info(file_path)
                
                # 发送信号
                self.log_opened.emit(file_path)
                
                # 如果启用了监控，启动监控线程
                if self.monitor_check.isChecked():
                    self._start_monitoring()
                
                logger.info(f"已打开日志文件: {file_path}")
                
            except Exception as e:
                logger.error(f"打开日志文件失败: {e}")
                QMessageBox.critical(self, "错误", f"打开日志文件失败: {str(e)}")
    
    def _read_log_file(self, file_path):
        """读取日志文件内容"""
        try:
            # 清空现有的日志内容
            self.log_table.setRowCount(0)
            self.log_text.clear()
            
            # 统计计数器
            level_counts = {"DEBUG": 0, "INFO": 0, "WARNING": 0, "ERROR": 0, "CRITICAL": 0}
            total_count = 0
            
            # 读取文件
            with open(file_path, 'r', encoding='utf-8', errors='replace') as file:
                lines = file.readlines()
                
                for line in lines:
                    line = line.strip()
                    if not line:
                        continue
                    
                    # 尝试解析日志行
                    # 假设日志格式为: 时间 级别 [来源] 消息
                    log_time, log_level, log_source, log_message = self._parse_log_line(line)
                    
                    # 添加到表格
                    row_position = self.log_table.rowCount()
                    self.log_table.insertRow(row_position)
                    
                    # 设置时间单元格
                    time_item = QTableWidgetItem(log_time)
                    self.log_table.setItem(row_position, 0, time_item)
                    
                    # 设置级别单元格
                    level_item = QTableWidgetItem(log_level)
                    # 设置颜色
                    if log_level in self.log_level_colors:
                        level_item.setForeground(self.log_level_colors[log_level])
                    self.log_table.setItem(row_position, 1, level_item)
                    
                    # 设置来源单元格
                    source_item = QTableWidgetItem(log_source)
                    self.log_table.setItem(row_position, 2, source_item)
                    
                    # 设置消息单元格
                    message_item = QTableWidgetItem(log_message)
                    self.log_table.setItem(row_position, 3, message_item)
                    
                    # 添加到文本视图
                    # 设置颜色
                    self.log_text.setTextColor(self.log_level_colors.get(log_level, QColor(0, 0, 0)))
                    self.log_text.append(line)
                    
                    # 更新统计
                    if log_level in level_counts:
                        level_counts[log_level] += 1
                    total_count += 1
            
            # 更新统计信息
            self.total_count_label.setText(str(total_count))
            for level, count in level_counts.items():
                if level in self.level_count_labels:
                    self.level_count_labels[level].setText(str(count))
            
            # 更新状态
            self.status_label.setText(f"已加载 {total_count} 条日志记录")
            
        except Exception as e:
            logger.error(f"读取日志文件失败: {e}")
            raise
    
    def _parse_log_line(self, line):
        """解析日志行
        
        尝试从日志行中提取时间、级别、来源和消息
        如果解析失败，返回默认值
        """
        try:
            # 简单的日志格式解析
            # 假设格式为: 2023-01-01 12:00:00,000 INFO [rpa.module] 消息内容
            parts = line.split(' ', 3)
            
            if len(parts) >= 4:
                log_time = f"{parts[0]} {parts[1]}"
                log_level = parts[2]
                
                # 提取来源和消息
                if '[' in parts[3] and ']' in parts[3]:
                    source_start = parts[3].index('[') + 1
                    source_end = parts[3].index(']')
                    log_source = parts[3][source_start:source_end]
                    
                    # 提取消息
                    if source_end + 1 < len(parts[3]):
                        log_message = parts[3][source_end + 1:].strip()
                    else:
                        log_message = ""
                else:
                    log_source = "unknown"
                    log_message = parts[3]
                
                return log_time, log_level, log_source, log_message
            else:
                # 如果解析失败，返回默认值
                return "", "UNKNOWN", "unknown", line
        except Exception:
            # 解析失败时返回默认值
            return "", "UNKNOWN", "unknown", line
    
    def _update_log_info(self, file_path):
        """更新日志文件信息"""
        try:
            # 获取文件信息
            file_stats = os.stat(file_path)
            
            # 更新路径
            self.log_path_label.setText(file_path)
            
            # 更新文件大小
            file_size_kb = file_stats.st_size / 1024
            if file_size_kb < 1024:
                self.file_size_label.setText(f"{file_size_kb:.2f} KB")
            else:
                file_size_mb = file_size_kb / 1024
                self.file_size_label.setText(f"{file_size_mb:.2f} MB")
            
            # 更新最后修改时间
            modified_time = datetime.fromtimestamp(file_stats.st_mtime)
            self.modified_time_label.setText(modified_time.strftime("%Y-%m-%d %H:%M:%S"))
            
        except Exception as e:
            logger.error(f"更新日志信息失败: {e}")
    
    def refresh_log(self):
        """刷新日志"""
        if self.current_log_path:
            try:
                # 停止监控
                self._stop_monitoring_thread()
                
                # 重新读取日志
                self._read_log_file(self.current_log_path)
                
                # 更新日志信息
                self._update_log_info(self.current_log_path)
                
                # 如果启用了监控，重新启动
                if self.monitor_check.isChecked():
                    self._start_monitoring()
                
                logger.info("已刷新日志")
                
            except Exception as e:
                logger.error(f"刷新日志失败: {e}")
                QMessageBox.critical(self, "错误", f"刷新日志失败: {str(e)}")
    
    def clear_log(self):
        """清空日志显示"""
        # 确认清空
        reply = QMessageBox.question(
            self, 
            "确认清空", 
            "确定要清空日志显示吗？这不会删除日志文件。",
            QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
        )
        
        if reply == QMessageBox.StandardButton.Yes:
            # 清空表格
            self.log_table.setRowCount(0)
            
            # 清空文本视图
            self.log_text.clear()
            
            # 清空详细信息
            self.detail_text.clear()
            
            # 更新统计
            self.total_count_label.setText("0")
            for level, label in self.level_count_labels.items():
                label.setText("0")
            
            # 更新状态
            self.status_label.setText("日志已清空")
            
            logger.info("日志显示已清空")
    
    def export_log(self):
        """导出日志"""
        if self.current_log_path:
            file_path, _ = QFileDialog.getSaveFileName(
                self, 
                "导出日志", 
                os.path.splitext(self.current_log_path)[0] + "_export.txt", 
                "文本文件 (*.txt);;日志文件 (*.log);;所有文件 (*)"
            )
            
            if file_path:
                try:
                    # 复制当前日志内容到新文件
                    with open(self.current_log_path, 'r', encoding='utf-8', errors='replace') as src:
                        with open(file_path, 'w', encoding='utf-8') as dst:
                            dst.write(src.read())
                    
                    # 更新状态
                    self.status_label.setText(f"日志已导出到: {file_path}")
                    
                    # 发送信号
                    self.log_exported.emit(file_path)
                    
                    logger.info(f"日志已导出到: {file_path}")
                    
                except Exception as e:
                    logger.error(f"导出日志失败: {e}")
                    QMessageBox.critical(self, "错误", f"导出日志失败: {str(e)}")
        else:
            QMessageBox.information(self, "提示", "请先打开一个日志文件")
    
    def toggle_monitoring(self, state):
        """切换日志监控状态"""
        if state == Qt.Checked:
            if self.current_log_path:
                self._start_monitoring()
            else:
                QMessageBox.information(self, "提示", "请先打开一个日志文件")
                self.monitor_check.setChecked(False)
        else:
            self._stop_monitoring_thread()
            self.status_label.setText("监控已停止")
    
    def _start_monitoring(self):
        """开始监控日志文件"""
        if self.current_log_path:
            # 停止之前的监控
            self._stop_monitoring_thread()
            
            # 创建并启动监控线程
            self.monitor_thread = LogMonitorThread(self.current_log_path)
            self.monitor_thread.new_log.connect(self._handle_new_log)
            self.monitor_thread.start()
            
            self.status_label.setText("正在监控日志文件...")
            
            logger.info(f"开始监控日志文件: {self.current_log_path}")
    
    def _stop_monitoring_thread(self):
        """安全停止监控线程"""
        if self.monitor_thread:
            try:
                # 调用线程的stop方法而不是直接wait
                self.monitor_thread.stop()
                self.monitor_thread = None
            except Exception as e:
                logger.error(f"停止监控线程失败: {e}")
                self.monitor_thread = None
    
    def _handle_new_log(self, log_line):
        """处理新的日志行"""
        try:
            # 解析日志行
            log_time, log_level, log_source, log_message = self._parse_log_line(log_line)
            
            # 添加到表格
            row_position = self.log_table.rowCount()
            self.log_table.insertRow(row_position)
            
            # 设置时间单元格
            time_item = QTableWidgetItem(log_time)
            self.log_table.setItem(row_position, 0, time_item)
            
            # 设置级别单元格
            level_item = QTableWidgetItem(log_level)
            # 设置颜色
            if log_level in self.log_level_colors:
                level_item.setForeground(self.log_level_colors[log_level])
            self.log_table.setItem(row_position, 1, level_item)
            
            # 设置来源单元格
            source_item = QTableWidgetItem(log_source)
            self.log_table.setItem(row_position, 2, source_item)
            
            # 设置消息单元格
            message_item = QTableWidgetItem(log_message)
            self.log_table.setItem(row_position, 3, message_item)
            
            # 添加到文本视图
            # 设置颜色
            self.log_text.setTextColor(self.log_level_colors.get(log_level, QColor(0, 0, 0)))
            self.log_text.append(log_line)
            
            # 滚动到最后一行
            self.log_text.moveCursor(QTextCursor.MoveOperation.End)
            
            # 更新统计
            total_count = int(self.total_count_label.text()) + 1
            self.total_count_label.setText(str(total_count))
            
            if log_level in self.level_count_labels:
                level_count = int(self.level_count_labels[log_level].text()) + 1
                self.level_count_labels[log_level].setText(str(level_count))
            
            # 更新状态
            self.status_label.setText(f"已加载 {total_count} 条日志记录")
            
            # 更新日志信息（文件大小、修改时间等）
            self._update_log_info(self.current_log_path)
            
        except Exception as e:
            logger.error(f"处理新日志行失败: {e}")
    
    def filter_logs(self):
        """过滤日志"""
        try:
            # 获取过滤条件
            level_filter = self.level_filter_combo.currentText()
            search_text = self.search_edit.text().lower()
            
            # 更新过滤信息
            filter_parts = []
            if level_filter != "全部":
                filter_parts.append(f"级别: {level_filter}")
            if search_text:
                filter_parts.append(f"搜索: {search_text}")
            
            if filter_parts:
                self.filter_info_label.setText(", ".join(filter_parts))
            else:
                self.filter_info_label.setText("无过滤")
            
            # 应用过滤
            for row in range(self.log_table.rowCount()):
                level_item = self.log_table.item(row, 1)
                message_item = self.log_table.item(row, 3)
                
                # 级别过滤
                level_match = (level_filter == "全部") or \
                             (level_item and level_item.text() == level_filter)
                
                # 搜索文本过滤
                search_match = (not search_text) or \
                              (message_item and search_text in message_item.text().lower())
                
                # 显示或隐藏行
                self.log_table.setRowHidden(row, not (level_match and search_match))
            
            # 更新状态
            visible_rows = sum(1 for row in range(self.log_table.rowCount()) 
                              if not self.log_table.isRowHidden(row))
            self.status_label.setText(f"显示 {visible_rows} 条日志记录")
            
        except Exception as e:
            logger.error(f"过滤日志失败: {e}")
            QMessageBox.critical(self, "错误", f"过滤日志失败: {str(e)}")
    
    def reset_filter(self):
        """重置过滤条件"""
        # 重置过滤控件
        self.level_filter_combo.setCurrentText("全部")
        self.search_edit.clear()
        
        # 显示所有行
        for row in range(self.log_table.rowCount()):
            self.log_table.setRowHidden(row, False)
        
        # 更新过滤信息
        self.filter_info_label.setText("无过滤")
        
        # 更新状态
        self.status_label.setText(f"显示 {self.log_table.rowCount()} 条日志记录")
    
    def filter_logs_by_time(self):
        """按时间范围过滤日志"""
        try:
            # 获取时间范围
            start_time = self.start_time_edit.dateTime().toPyDateTime()
            end_time = self.end_time_edit.dateTime().toPyDateTime()
            
            # 更新过滤信息
            self.filter_info_label.setText(f"时间范围: {start_time} - {end_time}")
            
            # 应用过滤
            visible_count = 0
            for row in range(self.log_table.rowCount()):
                # 如果行已经被其他过滤隐藏，跳过
                if self.log_table.isRowHidden(row):
                    continue
                
                time_item = self.log_table.item(row, 0)
                if time_item:
                    time_text = time_item.text()
                    try:
                        # 尝试解析时间
                        # 假设格式为: 2023-01-01 12:00:00,000
                        log_time = datetime.strptime(time_text.split(',')[0], "%Y-%m-%d %H:%M:%S")
                        
                        # 检查是否在时间范围内
                        in_range = start_time <= log_time <= end_time
                        self.log_table.setRowHidden(row, not in_range)
                        
                        if in_range:
                            visible_count += 1
                    except ValueError:
                        # 解析失败，显示该行
                        self.log_table.setRowHidden(row, False)
                        visible_count += 1
            
            # 更新状态
            self.status_label.setText(f"显示 {visible_count} 条日志记录")
            
        except Exception as e:
            logger.error(f"按时间过滤日志失败: {e}")
            QMessageBox.critical(self, "错误", f"按时间过滤日志失败: {str(e)}")
    
    def on_table_cell_clicked(self, row, column):
        """表格单元格点击事件"""
        # 获取该行的所有信息
        time_item = self.log_table.item(row, 0)
        level_item = self.log_table.item(row, 1)
        source_item = self.log_table.item(row, 2)
        message_item = self.log_table.item(row, 3)
        
        # 构建详细信息
        details = []
        if time_item:
            details.append(f"时间: {time_item.text()}")
        if level_item:
            details.append(f"级别: {level_item.text()}")
        if source_item:
            details.append(f"来源: {source_item.text()}")
        if message_item:
            details.append(f"消息: {message_item.text()}")
        
        # 更新详细信息视图
        self.detail_text.setText("\n".join(details))
    
    def show_table_context_menu(self, position):
        """显示表格右键菜单"""
        menu = QMenu()
        
        # 复制选中项
        copy_action = QAction("复制")
        copy_action.triggered.connect(self.copy_selected_cells)
        menu.addAction(copy_action)
        
        # 全选
        select_all_action = QAction("全选")
        select_all_action.triggered.connect(self.log_table.selectAll)
        menu.addAction(select_all_action)
        
        # 清除选择
        clear_selection_action = QAction("清除选择")
        clear_selection_action.triggered.connect(self.log_table.clearSelection)
        menu.addAction(clear_selection_action)
        
        # 分隔符
        menu.addSeparator()
        
        # 导出选中行
        export_selected_action = QAction("导出选中行")
        export_selected_action.triggered.connect(self.export_selected_rows)
        menu.addAction(export_selected_action)
        
        # 显示菜单
        menu.exec(self.log_table.viewport().mapToGlobal(position))
    
    def copy_selected_cells(self):
        """复制选中的单元格"""
        selected_items = self.log_table.selectedItems()
        if not selected_items:
            return
        
        # 按行和列排序
        selected_items.sort(key=lambda item: (item.row(), item.column()))
        
        # 构建文本
        text_lines = []
        current_row = -1
        current_line = []
        
        for item in selected_items:
            if item.row() != current_row:
                if current_line:
                    text_lines.append("\t".join(current_line))
                current_row = item.row()
                current_line = []
            
            current_line.append(item.text())
        
        # 添加最后一行
        if current_line:
            text_lines.append("\t".join(current_line))
        
        # 设置到剪贴板
        from PyQt6.QtGui import QClipboard
        from PyQt6.QtWidgets import QApplication
        
        clipboard = QApplication.clipboard()
        clipboard.setText("\n".join(text_lines))
        
        # 更新状态
        self.status_label.setText(f"已复制 {len(selected_items)} 个单元格")
    
    def export_selected_rows(self):
        """导出选中的行"""
        selected_rows = set()
        for item in self.log_table.selectedItems():
            selected_rows.add(item.row())
        
        if not selected_rows:
            QMessageBox.information(self, "提示", "请先选择要导出的行")
            return
        
        file_path, _ = QFileDialog.getSaveFileName(
            self, 
            "导出选中行", 
            "selected_logs.txt", 
            "文本文件 (*.txt);;所有文件 (*)"
        )
        
        if file_path:
            try:
                with open(file_path, 'w', encoding='utf-8') as file:
                    for row in sorted(selected_rows):
                        # 构建完整的日志行
                        time_text = self.log_table.item(row, 0).text() if self.log_table.item(row, 0) else ""
                        level_text = self.log_table.item(row, 1).text() if self.log_table.item(row, 1) else ""
                        source_text = self.log_table.item(row, 2).text() if self.log_table.item(row, 2) else ""
                        message_text = self.log_table.item(row, 3).text() if self.log_table.item(row, 3) else ""
                        
                        # 格式化为原始日志行格式
                        log_line = f"{time_text} {level_text} [{source_text}] {message_text}"
                        file.write(log_line + "\n")
                
                # 更新状态
                self.status_label.setText(f"已导出 {len(selected_rows)} 行到: {file_path}")
                
                logger.info(f"已导出 {len(selected_rows)} 行日志到: {file_path}")
                
            except Exception as e:
                logger.error(f"导出选中行失败: {e}")
                QMessageBox.critical(self, "错误", f"导出选中行失败: {str(e)}")


class LogMonitorThread(QThread):
    """日志监控线程"""
    
    # 定义信号
    new_log = pyqtSignal(str)
    
    def __init__(self, log_path):
        super().__init__()
        self.log_path = log_path
        self._stop_event = False
    
    def run(self):
        """线程运行方法"""
        try:
            # 获取文件大小
            file_size = os.path.getsize(self.log_path)
            
            while not self._stop_event:
                # 检查文件大小是否变化
                new_size = os.path.getsize(self.log_path)
                
                if new_size > file_size:
                    # 文件大小增加，读取新内容
                    with open(self.log_path, 'r', encoding='utf-8', errors='replace') as file:
                        file.seek(file_size)
                        new_lines = file.readlines()
                        
                        for line in new_lines:
                            line = line.strip()
                            if line:
                                self.new_log.emit(line)
                    
                    # 更新文件大小
                    file_size = new_size
                
                # 休眠一段时间
                time.sleep(0.5)
                
        except Exception as e:
            logger.error(f"日志监控线程错误: {e}")
    
    def stop(self):
        """停止线程"""
        self._stop_event = True
        self.wait()